package cn.iocoder.yudao.module.member.service.cardsecurity;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.api.file.FileApi;
import cn.iocoder.yudao.module.member.controller.app.cardsecurity.vo.*;
import cn.iocoder.yudao.module.member.controller.app.order.vo.AppMemberCertificateOrderVo;
import cn.iocoder.yudao.module.member.dal.dataobject.cardsecurity.CardSecurityDo;
import cn.iocoder.yudao.module.member.dal.dataobject.order.MemberCertificateOrderDo;
import cn.iocoder.yudao.module.member.dal.mysql.cardsecurity.CardSecurityMapper;
import cn.iocoder.yudao.module.member.service.order.CertificateOrderService;
import cn.iocoder.yudao.module.signature.validatap12status.dto.CertAndMobileprovisionDTO;
import cn.iocoder.yudao.module.signature.validatap12status.dto.CertInfoDTO;
import cn.iocoder.yudao.module.signature.validatap12status.dto.CertStatusDTO;
import cn.iocoder.yudao.module.signature.validatap12status.dto.DeviceInfoDTO;
import cn.iocoder.yudao.module.signature.validatap12status.util.CertUtil;
import cn.iocoder.yudao.module.signature.validatap12status.util.OCSPUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;

@Service
@Validated
@Slf4j
public class CardSecurityServiceImpl implements CardSecurityService {


    @Resource
    private CardSecurityMapper cardSecurityMapper;
    @Resource
    private CertificateOrderService certificateOrderService;
    @Resource
    private FileApi fileApi;

    //默认最高2000个卡密
    private static final Long CARD_NUMBER = 2000L;

    @Override
    @Transactional
    public void create(CardSecurityVo cardSecurityVo) {
        Long userId = getLoginUserId();
        Long index = cardSecurityMapper.selectCountByUserId(userId);
        //判断数量最多只能存在 2000个未掉签的数据
        if (CARD_NUMBER - index < cardSecurityVo.getNumber()) {
            throw new RuntimeException("数量最多只能存在 2000个卡密");
        }
        //操作编码 方便后期处理
        String operateCode = cardSecurityCreate();
        List<CardSecurityDo> saveData = new ArrayList<>();
        for (int i = 0; i < cardSecurityVo.getNumber(); i++) {
            CardSecurityDo data = new CardSecurityDo();
            data.setUserId(userId);
            data.setDeviceType(cardSecurityVo.getDeviceType());
            data.setVersionTypeCode(cardSecurityVo.getVersionTypeCode());
            data.setVersionTypeName(cardSecurityVo.getVersionTypeName());
            data.setPurchaseType(cardSecurityVo.getPurchaseType());
            data.setUseFlag(Boolean.FALSE);
            data.setCardSecurity(cardSecurityCreate());
            data.setStatus(0);
            data.setRemark(cardSecurityVo.getRemark());
            data.setOperateCode(operateCode);
            saveData.add(data);
        }
        cardSecurityMapper.insertBatch(saveData);

    }

    public static String cardSecurityCreate() {
        String cardKey = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
        return cardKey;
    }

    /**
     * 根据udid + 卡密兑换证书
     *
     * @param cardSecurityExchengeVo
     */
    @Override
    @Transactional
    public MemberCertificateOrderDo exchange(CardSecurityExchengeVo cardSecurityExchengeVo) {

        CardSecurityDo cardSecurityDo = cardSecurityMapper.selectCountByCardSecurityCode(cardSecurityExchengeVo.getCardSecurityCode());
        if (cardSecurityDo == null) {
            throw exception(CARD_NOT);

//            throw new RuntimeException("卡密不存在");
        }
        if (cardSecurityDo.getUseFlag()) {
            throw exception(CARD_EXCHANGE);
//            throw new RuntimeException("卡密已兑换");
        }
        if (cardSecurityDo.getStatus() == 1) {
            throw exception(CARD_EXCHANGE_STATUS);
//            throw new RuntimeException("当前卡密已被禁用");
        }
        cardSecurityDo.setUdid(cardSecurityExchengeVo.getUdid());
        cardSecurityDo.setUseFlag(Boolean.TRUE);
        cardSecurityDo.setStartDate(new Date());
        cardSecurityMapper.updateById(cardSecurityDo);
        //调用上传证书接口
        AppMemberCertificateOrderVo appMemberCertificateOrderVo = new AppMemberCertificateOrderVo();
        appMemberCertificateOrderVo.setUdid(cardSecurityExchengeVo.getUdid());
        appMemberCertificateOrderVo.setDeviceType(cardSecurityDo.getDeviceType());
        appMemberCertificateOrderVo.setVersionTypeCode(cardSecurityDo.getVersionTypeCode());
        appMemberCertificateOrderVo.setVersionTypeName(cardSecurityDo.getVersionTypeName());
        appMemberCertificateOrderVo.setClassType(cardSecurityDo.getPurchaseType());
        appMemberCertificateOrderVo.setDropFlag(Boolean.FALSE);
        appMemberCertificateOrderVo.setPoolType("0");
        appMemberCertificateOrderVo.setUserId(cardSecurityDo.getUserId());
        appMemberCertificateOrderVo.setCardSecurity(cardSecurityDo.getCardSecurity());
        try {
            log.info("创建设备入参{}", JSONUtil.toJsonStr(appMemberCertificateOrderVo));
            return certificateOrderService.createOrder(appMemberCertificateOrderVo);
        } catch (Exception e) {
//            throw new RuntimeException("兑换失败");
            throw exception(CARD_EXCHANGE_NOT, e.getMessage());
        }

    }

    @Override
    public PageResult<CardSecurityDo> page(CardSecurityQueryVo pageVO) {
        return cardSecurityMapper.selectPage(pageVO);
    }

    @Override
    public void enable(List<Long> ids) {
        cardSecurityMapper.updateStatusByIds(ids, CommonStatusEnum.ENABLE.getStatus());
    }

    @Override
    public void disable(List<Long> ids) {
        cardSecurityMapper.updateStatusByIds(ids, CommonStatusEnum.DISABLE.getStatus());
    }

    @Override
    public void delete(List<Long> ids) {
        cardSecurityMapper.deleteByIds(ids);
    }

    @Override
    public Long count() {
        Long userId = getLoginUserId();
        Long aLong = cardSecurityMapper.selectCountByUserId(userId);
        return CARD_NUMBER - aLong;
    }

    @Override
    public List<String> getCardList() {
        Long userId = getLoginUserId();
        //最后一次创建的卡密
        CardSecurityDo cardSecurityDo = cardSecurityMapper.selectLastOneByUserId(userId);
        if (cardSecurityDo == null) {
            throw new RuntimeException("无卡密");
        }
        List<CardSecurityDo> cardList = cardSecurityMapper.selectCardList(cardSecurityDo.getOperateCode());
        return cardList.stream().map(CardSecurityDo::getCardSecurity).collect(Collectors.toList());
    }

    @Override
    public Boolean dropSignature(CardSecurityExchengeVo cardSecurityExchengeVo) {

        MemberCertificateOrderDo memberCertificateOrderDo = certificateOrderService.getById(cardSecurityExchengeVo.getId());
        if (ObjectUtil.isNull(memberCertificateOrderDo)) {
            throw exception(USER_CERTIFICATE_ORDER_NOT_SELECT);
        }
        if (StrUtil.isEmpty(memberCertificateOrderDo.getP12Url())) {
            throw exception(FILEAPI_NOT);
        }
        try {
            String p12Path = CharSequenceUtil.subAfter(memberCertificateOrderDo.getP12Url(), "/get/", false);
            String p12Config = memberCertificateOrderDo.getP12Url().substring(memberCertificateOrderDo.getP12Url().indexOf("/file/") + "/file/".length(), memberCertificateOrderDo.getP12Url().indexOf("/get/"));
            String p12FilePath = fileApi.getFilePath(Long.valueOf(p12Config), p12Path);

            String p12Str = Base64Encoder.encode(FileUtil.readBytes(p12FilePath));
            CertStatusDTO certStatusDTO = OCSPUtil.checkCertStatus(p12Str, memberCertificateOrderDo.getP12Password(), 1);
            CertUtil.getCertInfo(p12Str, memberCertificateOrderDo.getP12Password(), certStatusDTO);
            log.info("设备{}证书掉签检查结果为:{}", memberCertificateOrderDo.getId(), JSON.toJSONString(certStatusDTO));
            memberCertificateOrderDo.setCerStatus(String.valueOf(certStatusDTO.getStatus()));
            if (certStatusDTO.getStatus() != 0 || (null != certStatusDTO.getCertRemainingDays() && certStatusDTO.getCertRemainingDays() < 0)) {
                memberCertificateOrderDo.setDropFlag(true);
            }
            certificateOrderService.updateById(memberCertificateOrderDo);
        } catch (Exception e) {
            log.error("设备{}证书掉签检查异常", memberCertificateOrderDo.getId(), e);
            throw exception(DROP_SIGNATURE_ERROR, e.getMessage());
        }

        return memberCertificateOrderDo.getDropFlag();
    }

    @Override
    public CertCheckVo certCheck(Long id) throws Exception {

        MemberCertificateOrderDo memberCertificateOrderDo = certificateOrderService.getById(id);
        Assert.notNull(memberCertificateOrderDo, "设备信息未找到");
        Assert.notBlank(memberCertificateOrderDo.getP12Url(), "P12文件未找到");
        Assert.notBlank(memberCertificateOrderDo.getMpUrl(), "描述文件未找到");
        String p12Path = CharSequenceUtil.subAfter(memberCertificateOrderDo.getP12Url(), "/get/", false);
        String p12Config = memberCertificateOrderDo.getP12Url().substring(memberCertificateOrderDo.getP12Url().indexOf("/file/") + "/file/".length(), memberCertificateOrderDo.getP12Url().indexOf("/get/"));
        String p12FilePath = fileApi.getFilePath(Long.valueOf(p12Config), p12Path);


        String mpPath = CharSequenceUtil.subAfter(memberCertificateOrderDo.getMpUrl(), "/get/", false);
        String mpConfig = memberCertificateOrderDo.getMpUrl().substring(memberCertificateOrderDo.getMpUrl().indexOf("/file/") + "/file/".length(), memberCertificateOrderDo.getMpUrl().indexOf("/get/"));
        String mpFilePath = fileApi.getFilePath(Long.valueOf(mpConfig), mpPath);


        String p12Str = Base64Encoder.encode(FileUtil.readBytes(p12FilePath));
        String mpStr = new String(FileUtil.readBytes(mpFilePath), "UTF-8");

        CertAndMobileprovisionDTO certAndMobileprovisionDTO = CertUtil.checkMobileProvesion(p12Str, mpStr, memberCertificateOrderDo.getP12Password());
        Assert.notNull(certAndMobileprovisionDTO, "证书检查失败");


        CertCheckVo certCheckVo = new CertCheckVo();


        MbCheckVo mbCheckVo = BeanUtil.copyProperties(certAndMobileprovisionDTO, MbCheckVo.class);
        certCheckVo.setMbCheckVo(mbCheckVo);

        certCheckVo.setCertInfoDTO(certAndMobileprovisionDTO.getCertInfoDTO());

        List<DeviceInfoDTO> deviceInfoList = certAndMobileprovisionDTO.getDeviceInfoList();
        log.info("设备比对匹配:{},{}", memberCertificateOrderDo.getUdid(), JSON.toJSONString(deviceInfoList));
        List<String> udids = deviceInfoList.stream().map(DeviceInfoDTO::getUdid).collect(Collectors.toList());
        log.info("描述文件udid:{}", JSON.toJSONString(udids));
        boolean deviceMatchFlag = udids.contains(memberCertificateOrderDo.getUdid().trim());
;
        certCheckVo.getCertInfoDTO().setMatchFlag(deviceMatchFlag);

        //设置证书状态
        Optional.ofNullable(certCheckVo.getCertInfoDTO()).map(CertInfoDTO::getStatus).ifPresent(integer -> memberCertificateOrderDo.setCerStatus(String.valueOf(integer)));
        if (null != certCheckVo.getCertInfoDTO()) {
            if (StringUtils.isNotBlank(certCheckVo.getCertInfoDTO().getExpireTime())) {
                memberCertificateOrderDo.setCerExpireTime(DateUtil.parseDateTime(certCheckVo.getCertInfoDTO().getExpireTime()));
            }
            memberCertificateOrderDo.setCerStatus(String.valueOf(certCheckVo.getCertInfoDTO().getStatus()));

        }
        if (!"0".equals(memberCertificateOrderDo.getCerStatus())) {
            memberCertificateOrderDo.setDropFlag(true);
        }
        certificateOrderService.updateById(memberCertificateOrderDo);

        certCheckVo.setAllCapabilities(certAndMobileprovisionDTO.getAllCapabilities());

        return certCheckVo;
    }


    public static void main(String[] args) {
//        try {
//            String mpStr = new String(FileUtil.readBytes("D:\\Users\\liujq\\wechat\\WeChat Files\\wxid_4qjp6xqz5cpw22\\FileStorage\\File\\2025-08\\65O9RQ_描述文件.mobileprovision"), "UTF-8");
//            CertAndMobileprovisionDTO certAndMobileprovisionDTO = CertUtil.checkMobileProvesion(
//                    Base64Encoder.encode(FileUtil.readBytes("D:\\Users\\liujq\\wechat\\WeChat Files\\wxid_4qjp6xqz5cpw22\\FileStorage\\File\\2025-08\\P7YOSI_证书文件(密码1).p12")) ,
//                    mpStr,"1");
//            log.info("证书检查结果:{}", JSON.toJSONString(certAndMobileprovisionDTO));
//        }catch (Exception e){
//            log.error("证书检查异常", e);
//        }
        List<DeviceInfoDTO> deviceInfoList = JSON.parseArray("[{\"udid\":\"3e712bd6a24b780cec65544040edbf08ee1b38c4\"}]", DeviceInfoDTO.class);
        boolean b = deviceInfoList.stream().anyMatch(deviceInfoDTO -> StringUtils.equals(deviceInfoDTO.getUdid(), "3e712bd6a24b780cec65544040edbf08ee1b38c4"));
        System.out.println(b);

    }
}
